import tensorflow as tf

tf.enable_eager_execution()

tfe = tf.contrib.eager # Shorthand for some symbols


from math import pi

def f(x):
      return tf.square(tf.sin(x))

assert f(pi/2).numpy() == 1.0

  # grad_f will return a list of derivatives of f
  # with respect to its arguments. Since f() has a single argument,
  # grad_f will return a list with a single element.

grad_f = tfe.gradients_function(f)
print(grad_f)
print(tf.abs(grad_f(pi/2)).numpy())
assert tf.abs(grad_f(pi/2)[0]).numpy() < 1e-7

def f(x):
  return tf.square(tf.sin(x))

def grad(f):
  return lambda x: tfe.gradients_function(f)(x)[0]

x = tf.lin_space(-2*pi, 2*pi, 100)  # 100 points between -2π and +2π

import matplotlib.pyplot as plt

plt.plot(x, f(x), label="f")
plt.plot(x, grad(f)(x), label="first derivative")
plt.plot(x, grad(grad(f))(x), label="second derivative")
plt.plot(x, grad(grad(grad(f)))(x), label="third derivative")
plt.legend()
plt.show()
